package com.zyd.service.blackcar.impl;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Maps;
import com.zyd.constants.ErrorDef;
import com.zyd.context.HeaderContext;
import com.zyd.dao.BlackCarSmsInfoDao;
import com.zyd.dao.SocketNowBlackCarDao;
import com.zyd.exception.BusinessException;
import com.zyd.io.model.*;
import com.zyd.io.page.OperateKey;
import com.zyd.io.page.PageBean;
import com.zyd.io.page.SearchKey;
import com.zyd.io.vo.page.MultiQueryPageVO;
import com.zyd.mappers.BlackCarEntityMapper;
import com.zyd.mappers.StationEntityMapper;
import com.zyd.mappers.VehicleEntityMapper;
import com.zyd.message.MessageSender;
import com.zyd.service.blackcar.BlackCarService;
import com.zyd.service.power.PowerService;
import com.zyd.thread.BlackCarThread;
import com.zyd.util.*;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BlackCarServiceImpl implements BlackCarService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private BlackCarEntityMapper mapper;

    @Autowired
    private PowerService powerService;

    @Autowired
    private BlackCarThread blackCarThread;

    @Override
    public PageBean<Map<String, Object>> findBlackcarPage(MultiQueryPageVO request) {

        String countSql = "select count(*)";
        String selectFields = "select a.*, b.vinno ";
        StringBuilder sql = new StringBuilder();
        sql.append(" from zydzn_blackcar a LEFT JOIN zydzn_vehicle b on a.tagcode = b.tagcode where a.dr = 0 and a.state=0 ");
        sql.append(disposeSql(request.getSearchKeys()));

        RolePowerEntity rolePowerEntity = powerService.queryPowerListByUserId((String) HeaderContext.get().get("userid"), "2010");
        if (rolePowerEntity != null && !org.springframework.util.StringUtils.isEmpty(rolePowerEntity.getArea())) {

            sql.append(" and b.newareaid in (" + SqlUtils.addIn(rolePowerEntity.getArea()) + ")");
        } else {
            return null;
        }
        System.out.println(sql);
        Long totalRows = jdbcTemplate.queryForObject(countSql + sql.toString(), Long.class);
        String pageSql = SqlUtils.addPage(selectFields + sql.toString(), request.getCurrentPage(), request.getPageSize());

        List<Map<String, Object>> maps = jdbcTemplate.queryForList(pageSql);


        PageBean<Map<String, Object>> pageBean = new PageBean<>(request.getCurrentPage(), request.getPageSize(), totalRows.intValue());
        pageBean.setItems(maps);
        return pageBean;
    }

    @Override
    public BlackCarEntity findBlackcar(String id) {
        BlackCarEntityKey key = new BlackCarEntityKey();
        key.setId(id);
        return mapper.selectByPrimaryKey(key);
    }

    @Override
    @Transactional//操作多张表开启声明式失误
    public void addBlackcar(BlackCarEntity blackCar) {
        blackCar.setId(UUIDUtil.getUUid());

        checkDataValidation(blackCar);

        BlackCarEntityExample example = new BlackCarEntityExample();
        example.or().andDrEqualTo(0).andTagcodeEqualTo(blackCar.getTagcode()).andStateEqualTo(0);

        long l = mapper.countByExample(example);

        if (l > 0) {
            throw new BusinessException(ErrorDef.SYSTEM_ERROR, "黑车已存在，请勿重复添加");
        }

        blackCar.setRegtime(ToolUtils.getNowTime());
        blackCar.setDr(0);
        mapper.insertSelective(blackCar);
        blackCarThread.addBlackCar(blackCar.getTagcode());

    }


    @Override
    @Transactional//操作多表启用声明式事务
    public void updateBlackcar(BlackCarEntity blackCar) {
        checkDataValidation(blackCar);

        blackCar.setTs(ToolUtils.getNowTime());

        mapper.updateByPrimaryKeySelective(blackCar);
    }

    @Override
    @Transactional//操作多长表启用声明式事物
    public void deleteBlackcar(String id) {
        BlackCarEntity blackCarEntity = new BlackCarEntity();
        blackCarEntity.setId(id);
        blackCarEntity.setDr(1);
        blackCarEntity.setTs(ToolUtils.getNowTime());
        mapper.updateByPrimaryKeySelective(blackCarEntity);
        BlackCarEntityKey key = new BlackCarEntityKey();
        key.setId(id);
        BlackCarEntity selectByPrimaryKey = mapper.selectByPrimaryKey(key);
        blackCarThread.delete(selectByPrimaryKey.getTagcode());
    }

    @Override
    public Map<String, Object> blackWarn() {
        //and iswarn=0
        StringBuilder sql = new StringBuilder();
        sql.append("select count(1) from zydzn_vehiclerecord a LEFT JOIN zydzn_vehicle b on a.tagcode = b.tagcode where a.islock=1 and a.iswarn=0 ");

        RolePowerEntity rolePowerEntity = powerService.queryPowerListByUserId((String) HeaderContext.get().get("userid"), "2010");
        if (rolePowerEntity != null && !org.springframework.util.StringUtils.isEmpty(rolePowerEntity.getArea())) {

            sql.append(" and b.newareaid in (" + SqlUtils.addIn(rolePowerEntity.getArea()) + ")");
        } else {
            return null;
        }
        System.out.println(sql);
        Long ret = jdbcTemplate.queryForObject(sql.toString(), Long.class);


        if (ret > 0) {
            String timeSql = "select max(regtime) as regtime from zydzn_vehiclerecord where islock=1 and iswarn=0";
            String lastTime = jdbcTemplate.queryForObject(timeSql, String.class);
            if (!ToolUtils.isEmpty(lastTime)) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    Date lastDate = format.parse(lastTime);
                    Interval interval = new Interval(lastDate.getTime(), new Date().getTime());
                    Period period = interval.toPeriod(PeriodType.minutes());

                    if (period.getMinutes() > 3) {
                        String updateSql = "update zydzn_vehiclerecord set iswarn=1 where iswarn=0";
                        jdbcTemplate.update(updateSql);
                    }

                } catch (ParseException e) {

                }
            }

        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("iswarn", ret > 0);
        return map;
    }

    /**
     * @param carid 黑车Id
     * @return
     */
    @Override
    public Map findBlackcarId(String carid) {
        String sql = "select img1,img2,img3 from zydzn_vehicle v where v.tagcode= '" + carid + "'";
        System.out.println(sql);
        Map<String, Object> map = jdbcTemplate.queryForMap(sql);
        return map;
    }

    /**
     * 查询最新的行车记录
     *
     * @param tag_id
     * @return
     */
    @Override
    public Map findByCommonCode(String tag_id) {
        String sql = "SELECT a.stationcode,a.address,a.stationname,b.tag_id,DATE_FORMAT(b.rec_time,'%Y-%m-%d %H:%i:%s') as aftertime FROM  socket_now b  left JOIN  zydzn_station a on a.stationcode = b.base_id  where a.stationcode is not null  and a.dr=0 and  b.tag_id = ?  ORDER BY b.rec_time desc limit 1";
        Map<String, Object> map = null;
        try {
            map = jdbcTemplate.queryForMap(sql, tag_id);
        } catch (DataAccessException e) {
            System.out.println("没有查询到数据通过tag_id=" + tag_id);
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 必要验证
     *
     * @return
     */
    private String checkErrorMsg(BlackCarEntity blackCarEntity) {
        String errmsg = "";
        if (StringUtils.isEmpty(blackCarEntity.getCarname())) {
            errmsg = "车主姓名不能为空!";
            return errmsg;
        } else if (StringUtils.isEmpty(blackCarEntity.getMobile())) {
            errmsg = "手机号码不能为空!";
            return errmsg;
        } else if (StringUtils.isEmpty(blackCarEntity.getCarid())) {
            errmsg = "车主身份证不能为空!";
            return errmsg;
        } else if (StringUtils.isEmpty(blackCarEntity.getTheftnum())) {
            errmsg = "车架号不能为空!";
            return errmsg;
        } else if (StringUtils.isEmpty(blackCarEntity.getTagcode())) {
            errmsg = "防盗芯片不能为空!";
            return errmsg;
        } else if (StringUtils.isEmpty(blackCarEntity.getAddress())) {
            errmsg = "丢失地点不能为空!";
            return errmsg;
        }
        return errmsg;
    }

    private void checkDataValidation(BlackCarEntity vehicle) {
        String validation = checkErrorMsg(vehicle);
        if (StringUtils.isNotBlank(validation)) {
            throw new BusinessException(ErrorDef.SYSTEM_ERROR, validation);
        }
    }

    //黑车统计查询   只查询已找回的 和为删除的
    @Override
    public PageBean<Map<String, Object>> blackCarFindPage(MultiQueryPageVO request) {
        String str = "select a.*, b.vinno FROM zydzn_blackcar a LEFT JOIN zydzn_vehicle b ON a.tagcode=b.tagcode WHERE a.state=1 AND a.dr=0 ";
        String pageSqlseach = str + disposeSql(request.getSearchKeys());

        RolePowerEntity rolePowerEntity = powerService.queryPowerListByUserId((String) HeaderContext.get().get("userid"), "2010");

        if (rolePowerEntity != null && !org.springframework.util.StringUtils.isEmpty(rolePowerEntity.getArea())) {
            pageSqlseach += " and b.newareaid in (" + SqlUtils.addIn(rolePowerEntity.getArea()) + ")";
        } else {
            return null;
        }
        String countSql = "select count(1) from (" + pageSqlseach + ") as b";
        Long totalRows = jdbcTemplate.queryForObject(countSql, Long.class);
        String pageSql = SqlUtils.addPage(pageSqlseach, request.getCurrentPage(), request.getPageSize());
        List<Map<String, Object>> ret = jdbcTemplate.query(pageSql, new RowMapper<Map<String, Object>>() {
            @Override
            public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
                Map<String, Object> ret = Maps.newHashMap();
                ret.put("carname", rs.getString("carname"));
                ret.put("carid", rs.getString("carid"));
                ret.put("vinno", rs.getString("vinno"));
                ret.put("missingtime", rs.getString("missingtime"));
                ret.put("ts", rs.getString("ts"));
                return ret;
            }
        });

        PageBean<Map<String, Object>> pageBean = new PageBean<Map<String, Object>>(request.getCurrentPage(), request.getPageSize(), totalRows.intValue());
        pageBean.setItems(ret);
        return pageBean;
    }
//    找回时间

    public void disposeTime(BlackCarEntity vehicle) {
        String stateSql = "SELECT  carid,state FROM zydzn_blackcar  ";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(stateSql);
        for (Map<String, Object> map : maps) {
            System.out.println(map.get("carid") + " " + map.get("state"));
            System.out.println(vehicle.getCarid() + "   " + vehicle.getState());
            //carid身份比较     修改state状态是1的情况   修改的状态和数据库查的状态不可以一样
            if (map.get("carid").equals(vehicle.getCarid()) && vehicle.getState() == 1 && vehicle.getState() != map.get("state")) {
                //获取当前时间 ：ToolUtils.getNowTime()
                vehicle.setTs(ToolUtils.getNowTime());

            }
        }

    }

    @Autowired
    private SocketNowBlackCarDao socketNowBlackCarDao;

    @Override
    public List getBlackInfo() {
        return socketNowBlackCarDao.findTrackBy5Minute();
    }

    @Autowired
    private BlackCarSmsInfoDao blackCarSmsInfoDao;

    /**
     * 通过area 查询对应地区黑车的发送短信的列表
     *
     * @param area
     * @return
     */
    @Override
    public List findBlackSmsInfo(String area) {
        return blackCarSmsInfoDao.findByArea(area);
    }

    /**
     * 添加或者修改
     *
     * @param param
     * @return
     */
    @Override
    public void saveBlackSmsInfo(Map<String, String> param) {
        if (!org.springframework.util.StringUtils.isEmpty(param.get("name")) &&
                !org.springframework.util.StringUtils.isEmpty(param.get("mobile")) &&
                !org.springframework.util.StringUtils.isEmpty(param.get("area"))) {
            if (!ValidationUtil.isPhoneNumber(param.get("mobile"))) {
                throw new BusinessException("请填写正确的手机号");
            }
            if (org.springframework.util.StringUtils.isEmpty(param.get("id"))) {
                blackCarSmsInfoDao.insert(param);
            }else {
                blackCarSmsInfoDao.updateById(param);
            }
        }else {
            throw new BusinessException("参数不正确");
        }

    }

    /**
     * 根据id删除
     *
     * @param id
     */
    @Override
    public void deleteBlackSmsInfo(String id) {
        blackCarSmsInfoDao.deleteById(id);
    }

    @Value("${blackCarTemplateCode}")
    private String templateCode;

    @Autowired
    private MessageSender messageSender;

    @Value("${signName}")
    private String signName;


    @Autowired
    private VehicleEntityMapper vehicleEntityMapper;

    @Autowired
    private StationEntityMapper stationMapper;
    /**
     * 缓存基站编号跟标签号,为了不重复发送短信
     */
    private HashMap<String,String> map=new HashMap<>();
    /**
     * 发送短信
     *
     * @param baseId 基站编号
     * @param tagId 黑车标签号
     */
    @Override
    public void smsInfo(String baseId,String tagId) {
        String oldBaseId = map.get(tagId);
        /**
         * 如果当前车辆存在之前的基站记录or等于当前的基站就不发送短信了
         */
        if (!org.springframework.util.StringUtils.isEmpty(oldBaseId) &&
                oldBaseId.equals(baseId)) {
            return;
        }
        map.put(tagId,baseId);
        VehicleEntityExample example =new VehicleEntityExample();
        example.createCriteria().andTagcodeEqualTo(tagId).andDrEqualTo(0);
        StationEntityExample stationExample =new StationEntityExample();
        stationExample.createCriteria().andDrEqualTo(0).andStationcodeEqualTo(baseId);
        VehicleEntity vehicleEntity;
        StationEntity stationEntity;
        try {
            vehicleEntity = vehicleEntityMapper.selectByExample(example).get(0);
            stationEntity = stationMapper.selectByExample(stationExample).get(0);
        } catch (Exception e) {
            return;
        }

        String param = "{\"vinno\":\"" + vehicleEntity.getVinno() + "\",\"tagCode\":\"" +tagId + "\",\"name\":\"" +vehicleEntity.getCarname() + "\",\"stationName\":\"" +stationEntity.getAddress() + "\",\"stationCode\":\"" + baseId + "\"}";
        List<String> mobiles = blackCarSmsInfoDao.findMobileByArea(stationEntity.getArea());
        for (String mobile : mobiles) {
            SendSmsResponse sendSmsResponse = null;
            try {
                sendSmsResponse = messageSender.sendSms(mobile, signName, templateCode, param);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            System.out.println(sendSmsResponse.getMessage());
        }

    }

    //    处理sql
    public String disposeSql(List<SearchKey> searchKeys) {
        StringBuilder sql = new StringBuilder();
        for (SearchKey searchKey : searchKeys) {
            sql.append("  and a. " + searchKey.getName() + " " + searchKey.getOperate() + " ");
            if (searchKey.getOperate().equalsIgnoreCase(OperateKey.LIKE)) {
                sql.append("\'" + SqlUtils.andLike(searchKey.getValue()) + "\'");
            } else {
                //支持 =、>、<、!=、like、in、notin
                sql.append("\'" + searchKey.getValue() + "\'");
            }
        }
        return sql.toString();
    }
}

